﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public static string updateurl = @"http://add_the_new_address_here_and_press_enter_or_click_on_set_new/";
        public const string imagesOfilepath = @"Content/Images/";
        public const string imagesLfilepath = @"Content\Images\";
        public const string soundsOfilepath = @"Content/Sounds/";
        public const string soundsLfilepath = @"Content\Sounds\";
        public const string fileslist = "files.txt";
        public const string imageslist = "images.txt";
        public const string soundslist = "sounds.txt";
        public const string urlfilename = "url.txt";
        public static List<string> fileslistonuseO = new List<string>();
        public static List<string> imageslistonuseO = new List<string>();
        public static List<string> soundslistonuseO = new List<string>();
        public static List<string> fileslistonuseL = new List<string>();
        public static List<string> imageslistonuseL = new List<string>();
        public static List<string> soundslistonuseL = new List<string>();
        private bool filesonfocus;
        private bool imagesonfocus;
        private bool soundsonfocus;
        private bool locselectall;
        private bool onselectall;
        public Form1()
        {
            InitializeComponent();

        }
        private void update_all_click(object sender, EventArgs e)
        {
            Files_Click(sender, e);
            Update_Click(sender, e);
            Images_Click(sender, e);
            Update_Click(sender, e);
            Sounds_Click(sender, e);
            Update_Click(sender, e);
        }
        private void main_windown_load(object sender, EventArgs e)
        {
            initialize();

        }
        private void Files_Click(object sender, EventArgs e)
        {
            this.loadlists(1);


        }
        private void Images_Click(object sender, EventArgs e)
        {
            this.loadlists(2);

        }
        private void Sounds_Click(object sender, EventArgs e)
        {
            this.loadlists(3);


        }
        private void Update_Click(object sender, EventArgs e)
        {
            if (filesonfocus)
            {
                this.AppendTextBoxLine("updating Files..please wait");
                if (update())
                {
                    this.AppendTextBoxLine("files download or update");
                    if (updateversions( fileslist))
                    {
                        this.AppendTextBoxLine("files list updated");
                        fileslistonuseL.Clear();
                        this.loadlists(1);
                    }
                }
                filesonfocus = true;
            }
            if (imagesonfocus)
            {

                this.AppendTextBoxLine("updating Images..please wait");
                if (update( imagesOfilepath, imagesLfilepath))
                {

                    if (updateversions( imageslist))
                    {
                        this.AppendTextBoxLine("images list updated");
                        imageslistonuseL.Clear();
                        this.loadlists(2);
                    }
                }
                imagesonfocus = true;
            }
            if (soundsonfocus)
            {

                this.AppendTextBoxLine("updating Sounds..please wait");
                if (update( soundsOfilepath, soundsLfilepath))
                {

                    if (updateversions(soundslist))
                    {
                        this.AppendTextBoxLine("sounds list updated");
                        soundslistonuseL.Clear();
                        this.loadlists(3);
                    }
                }

            }
        }
        public bool update(string pathOnline = "", string pathLocal = "")
        {
         
            bool result = false;
            for (int j = 0; j < OnlinelistBox.CheckedIndices.Count; j++)
            {

                string[] wordsO = (OnlinelistBox.Items[OnlinelistBox.CheckedIndices[j]].ToString()).Split(' ');
                if (wordsO.LongLength == 2)
                {
                  string nameO = wordsO[0];
                  string  versionO = wordsO[1];

                  this.AppendTextBoxLine("stage 1 passed.");

                    string[] wordsL = (this.comparetolocalname(nameO)).Split(' ');
                    if (wordsL.LongLength == 2)
                    {
                       string nameL = wordsL[0];
                       string versionL = wordsL[1];

                       this.AppendTextBoxLine("stage 2 passed.");
                        if (nameO == nameL)
                        {
                            int VL = Convert.ToInt32(versionL);
                            int VO = Convert.ToInt32(versionO);
                            if (VO != VL)
                            {

                                if (downloadfile(updateurl + pathOnline + nameL, pathLocal + nameL + "_new"))
                                {
                                    if (updatefile(pathLocal + nameL + "_new", pathLocal + nameL))
                                    {
                                        if (System.IO.File.Exists(pathLocal + nameO + "_new"))
                                        {

                                            this.AppendTextBoxLine("Deleting temporary files...");
                                            System.IO.File.Delete(pathLocal + nameL + "_new");
                                            Thread.Sleep(500);
                                            result = true;
                                            this.comparetolocalname(nameO, true, versionO);
                                       
                                        }
                                    }
                                }
                            }
                            else
                            {
                                this.AppendTextBoxLine(nameL + " is up to date");
                            }
                        }
                        else
                        {

                            if (downloadfile(updateurl + pathOnline + nameO, pathLocal + nameO))
                            {
                                LocallistBox.Items.Add(OnlinelistBox.Items[OnlinelistBox.CheckedIndices[j]].ToString());
                                result = true;
                            }

                        }
                    }
                }
            }
            return result;
        }
        public bool delete(string pathLocal = "")
        {
        
            bool result = false;
            int[] count = new int[LocallistBox.CheckedIndices.Count];
            foreach (int j in count)
            {
                string nameO = "";
                string[] wordsO = (LocallistBox.Items[LocallistBox.CheckedIndices[j]].ToString()).Split(' ');
                if (wordsO.LongLength == 2)
                {
                    nameO = wordsO[0];
                }

                if (System.IO.File.Exists(pathLocal + nameO))
                {
                    this.AppendTextBoxLine("Deleting files: " + nameO);
                    System.IO.File.Delete(pathLocal + nameO);
                    Thread.Sleep(250);
                    LocallistBox.Items.RemoveAt(LocallistBox.CheckedIndices[j]);
                    result = true;
                }
                else { this.AppendTextBoxLine("file does not exist."); result = true; }
            }
            return result;
        }
        public void loadlists(int type = 0)
        {
            if (type == 1)
            {
                OnlinelistBox.Items.Clear();
                LocallistBox.Items.Clear();

                if (fileslistonuseL.Count == 0)
                {
                    fileslistonuseL = getLOClist(fileslist);
                }
                for (int i = 0; i < fileslistonuseL.Count; i++)
                {
                    LocallistBox.Items.Add(fileslistonuseL[i].ToString());
                }
                if (fileslistonuseO.Count == 0)
                {
                    fileslistonuseO = getONlist(updateurl + fileslist);
                }
                for (int i = 0; i < fileslistonuseO.Count; i++)
                {

                    OnlinelistBox.Items.Add(fileslistonuseO[i].ToString(), true);


                }
                filesonfocus = true;
                imagesonfocus = false;
                soundsonfocus = false;

            }
            if (type == 2)
            {
                OnlinelistBox.Items.Clear();
                LocallistBox.Items.Clear();

                if (imageslistonuseL.Count == 0)
                {
                    imageslistonuseL = getLOClist(imageslist);

                }
                for (int i = 0; i < imageslistonuseL.Count; i++)
                {
                    LocallistBox.Items.Add(imageslistonuseL[i].ToString());
                }
                if (imageslistonuseO.Count == 0)
                {
                    imageslistonuseO = getONlist(updateurl + imageslist);

                }
                for (int i = 0; i < imageslistonuseO.Count; i++)
                {


                    OnlinelistBox.Items.Add(imageslistonuseO[i].ToString(), true);



                }
                filesonfocus = false;
                imagesonfocus = true;
                soundsonfocus = false;

            }
            if (type == 3)
            {
                OnlinelistBox.Items.Clear();
                LocallistBox.Items.Clear();
                if (soundslistonuseL.Count == 0)
                {
                    soundslistonuseL = getLOClist(soundslist);

                }
                for (int i = 0; i < soundslistonuseL.Count; i++)
                {
                    LocallistBox.Items.Add(soundslistonuseL[i].ToString());
                }

                if (soundslistonuseO.Count == 0)
                {
                    soundslistonuseO = getONlist(updateurl + soundslist);
                }
                for (int i = 0; i < soundslistonuseO.Count; i++)
                {



                    OnlinelistBox.Items.Add(soundslistonuseO[i].ToString(), true);



                }


                filesonfocus = false;
                imagesonfocus = false;
                soundsonfocus = true;

            }
        }
        private void Delete_Click(object sender, EventArgs e)
        {


            if (filesonfocus)
            {
                this.loadlists();
                filesonfocus = true;
                this.AppendTextBoxLine("deleting files");
                if (delete())
                {
                    if (updateversions( fileslist))
                    {
                        this.AppendTextBoxLine("files list updated");
                        fileslistonuseL.Clear();
                        this.loadlists(1);
                    }
                }
            }
            if (imagesonfocus)
            {
                this.AppendTextBoxLine("deleting Images");
                if (delete(imagesLfilepath))
                {
                    if (updateversions(imageslist))
                    {
                        this.AppendTextBoxLine("images list updated");
                        imageslistonuseL.Clear();
                        this.loadlists(2);
                    }
                }
            }
            if (soundsonfocus)
            {
                this.AppendTextBoxLine("deleting Sounds");
                if (delete(soundsLfilepath))
                {
                    if (updateversions(soundslist))
                    {
                        this.AppendTextBoxLine("sounds list updated");
                        soundslistonuseL.Clear();
                        this.loadlists(3);
                    }
                }
            }
        }
        private void SET_Click(object sender, EventArgs e)
        {
            
            updateurl = URLcombobox.Text.ToString();
            if (!updateurl.StartsWith("http://") &&
                !updateurl.StartsWith("https://"))
            {
                updateurl = "http://" + updateurl;
            }
            if (!updateurl.EndsWith("/"))
            {
                updateurl = updateurl + "/";
            }
            URLcombobox.Text = updateurl;
            URLcombobox.Items.Add(updateurl);

            SET.BackColor = Color.LimeGreen;
            if (System.IO.File.Exists(urlfilename))
            {
                TextWriter writer = new StreamWriter(urlfilename);
                for (int i = 0; i < URLcombobox.Items.Count; i++)
                {
                    writer.WriteLine(URLcombobox.Items[i].ToString());
                }
                writer.Close();
                this.AppendTextBoxLine("url written to file");
            }
        }
        public void initialize()
        {
           
            createtext(urlfilename);
            createdirectory("Content");
            createdirectory(@"Content\Images");
            createdirectory(@"Content\Sounds");
            createtext(fileslist);
            createtext(imageslist);
            createtext(soundslist);
            seturl(urlfilename);
           if (URLcombobox.Items.Count >=1)
           {
                // URLcombobox.SelectedItem;
            URLcombobox.SelectedValue = 1;
               

           }
            this.AppendTextBoxLine("checking for original executables...");
            if (
                checkfororiginalbak("Terraria.exe_original", "Terraria.exe") ||
                checkfororiginalbak("TerrariaServer.exe_original", "TerrariaServer.exe")
                || (System.IO.File.Exists("TerrariaServer.exe_original")) || (System.IO.File.Exists("Terraria.exe_original"))
                )
            {
                this.AppendTextBoxLine("executables are backed up");

            }
            else { this.AppendTextBoxLine("could not backup or theres are not executables in this folder"); }
            this.AppendTextBoxLine("lists will be downloaded only once unless you change url.");
        }
        private bool createtext(string path)
        {
            bool result = false;
            if (!System.IO.File.Exists(path))
            {
                StreamWriter MyStream = null;
                try
                {
                    MyStream = File.CreateText(path);
                }
                catch (IOException e)
                {
                    Console.WriteLine(e);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                finally
                {
                    if (MyStream != null)
                        MyStream.Close();
                    result = true;
                }
            }
            return result;
        }
        private void createdirectory(string p)
        {
            if (!System.IO.Directory.Exists(p))
            {
                System.IO.Directory.CreateDirectory(p);
            }
        }
        private bool seturl(string path)
        {
            bool result = false;
            if (!System.IO.File.Exists(path))
            {
                System.IO.File.Create(path);
            }
            else
            {
                using (StreamReader reader = new StreamReader(path))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line != "")
                        {
                            URLcombobox.Items.Add(line);
                        }
                    }
                }
            }
            return result;
        }
        private bool checkfororiginalbak(string O, string S)
        {
            bool result = false;
            if (!System.IO.File.Exists(O))
            {

                if (System.IO.File.Exists(S))
                {
                    System.IO.File.Copy(S, O);
                    Thread.Sleep(500);
                    result = true;
                }
            }
            return result;
        }
        public List<string> getONlist(string url)
        {
            this.AppendTextBoxLine("getting online list");
            List<string> Content = new List<string>();
            try
            {
                WebRequest request = (HttpWebRequest)WebRequest.Create(url);
                Stream responseStream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line != "")
                        {
                            Content.Add(line);
                            this.AppendTextBoxLine("online: " + line);
                        }
                    }
                }
                responseStream.Close();
            }
            catch (WebException exception)
            {
                this.AppendTextBoxLine("Error while checking for updates: " + exception.Message);

            }
            return Content;
        }
        public List<string> getLOClist(string path)
        {
            this.AppendTextBoxLine("getting local list");
            List<string> Content = new List<string>();
            if (!System.IO.File.Exists(path))
            {
                System.IO.File.Create(path);
            }
            else
            {
                using (StreamReader reader = new StreamReader(path))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line != "")
                        {
                            Content.Add(line);
                            this.AppendTextBoxLine("local: " + line);
                        }
                    }
                }
            }
            return Content;
        }
        private string comparetolocalname(string oname,bool updateV = false,string versionO="")
        {
            string result = "noname 0";
            for (int i = 0; i < LocallistBox.Items.Count; i++)
            {
                string[] wordsL = (LocallistBox.Items[i].ToString()).Split(' ');
                if (wordsL.LongLength == 2)
                {
                    if (wordsL[0] == oname)
                    {
                        if (!updateV)
                        {
                            result = LocallistBox.Items[i].ToString();

                        }
                        else
                        {
                            LocallistBox.Items.RemoveAt(i);
                            LocallistBox.Items.Insert(i, oname + " " + versionO);
                        }
                    }
                }
            }
            return result;
        }
        private bool downloadfile(string urlsource, string dest)
        {
            bool result = false;
            try
            {
                if (System.IO.File.Exists(dest))
                { System.IO.File.Delete(dest); }
                WebClient client = new WebClient();
                this.AppendTextBoxLine("downloading: " + urlsource);
                client.DownloadFile(urlsource, dest);
            }
            catch (WebException exception)
            {
                this.AppendTextBoxLine("Error while downlnoading new version of  " + urlsource + " " + exception.Message);
                this.AppendTextBoxLine("......");

            }
            if (System.IO.File.Exists(dest))
            {
                result = true;
            }
            return result;
        }
        private bool updatefile(string source, string destination)
        {

            bool result = false;
            this.AppendTextBoxLine("Updating: " + destination);
            if (System.IO.File.Exists(destination))
            {
                this.AppendTextBoxLine("Deleting old version...");
                System.IO.File.Delete(destination);
            }
            this.AppendTextBoxLine("applying new version");
            System.IO.File.Copy(source, destination);
            result = true;
            return result;
        }
        public bool updateversions(string path)
        {
            this.AppendTextBoxLine("updating: " + path);
            bool result = false;
            if (System.IO.File.Exists(path))
            {
                TextWriter writer = new StreamWriter(path);
                for (int index = 0; index < LocallistBox.Items.Count; index++)
                {
                    writer.WriteLine(LocallistBox.Items[index].ToString());
                }
                writer.Close();
                result = true;
            }
            else
            {
                System.IO.File.Create(path);

            }
            return result;

        }
        private void AppendTextBoxLine(string myStr)
        {
            if (textBox1.Text.Length > 0)
            {
                textBox1.AppendText(Environment.NewLine);
            }
            textBox1.AppendText(myStr);
        }
        private void localselectAllbutton(object sender, EventArgs e)
        {
            if (!locselectall)
            {
                for (int i = 0; i < LocallistBox.Items.Count; i++)
                {

                    LocallistBox.SetItemChecked(i, true);


                }
                locselectall = true;
            }
            else
            {
                for (int i = 0; i < LocallistBox.Items.Count; i++)
                {

                    LocallistBox.SetItemChecked(i, false);


                }
                locselectall = false;
            }

        }
        private void onlineselectAllbutton(object sender, EventArgs e)
        {
            if (onselectall)
            {
                for (int i = 0; i < OnlinelistBox.Items.Count; i++)
                {

                    OnlinelistBox.SetItemChecked(i, true);


                }
                onselectall = false;
            }
            else
            {
                for (int i = 0; i < OnlinelistBox.Items.Count; i++)
                {

                    OnlinelistBox.SetItemChecked(i, false);

                }
                onselectall = true;
            }
        }
        private void button4_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < OnlinelistBox.Items.Count; i++)
            {
                if (OnlinelistBox.GetItemChecked(i))
                {
                    OnlinelistBox.SetItemChecked(i, false);

                }
                else { OnlinelistBox.SetItemChecked(i, true); }



            }

      
        }
        private void button5_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < LocallistBox.Items.Count; i++)
            {
                if (LocallistBox.GetItemChecked(i))
                {
                    LocallistBox.SetItemChecked(i, false);

                }
                else { LocallistBox.SetItemChecked(i, true); }



            }
        }





        private void ImputBOX_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                SET_Click(sender, e);
            }
            if (e.KeyChar == (char)27)
            {

                URLcombobox.Text = "";
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            updateurl = URLcombobox.SelectedItem.ToString();
            fileslistonuseO.Clear();
            imageslistonuseO.Clear();
            soundslistonuseO.Clear();
            OnlinelistBox.Items.Clear();
            this.AppendTextBoxLine("url changed.... you can check for updates again.");
        
        }

      



    }
}
